#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#define NUM 1024

struct MYFILE{
  int fd;
  char buffer[NUM];
  int end;
};

typedef struct MYFILE MYFILE;

MYFILE *_fopen(const char *pathname, const char *mode){
  assert(pathname!=NULL); 
  assert(mode!=NULL);

  MYFILE *fp = NULL;
  if(strcmp(mode, "w") == 0)
  {
    int fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if(fd >= 0)
    {
      fp = (MYFILE*)malloc(sizeof(MYFILE));
      fp->fd = fd;
      memset(fp->buffer, '\0', sizeof(fp->buffer));
      fp->end = 0;
    }
  }
  else if(strcmp(mode, "w+") == 0)
  {
  
  }
  else if(strcmp(mode, "r") == 0)
  {

  }
  else if(strcmp(mode, "r+") == 0)
  {

  }
  else if(strcmp(mode, "a") == 0)
  {
     
  }
  else if(strcmp(mode, "a+") == 0)
  {

  }
  else{

  }
  return fp;
}

void _fputs(const char *message, MYFILE *fp){
  assert(message != NULL);
  assert(fp != NULL);

  strcpy(fp->buffer+fp->end, message);
  fp->end += strlen(message);
  fprintf(stderr, "buffer:%s", fp->buffer);
  switch(fp->fd)
  {
    case 0:
      break;
    case 1:
      if(fp->buffer[fp->end-1] == '\n')
      {
        fprintf(stderr, "flush:%s", fp->buffer);
        write(fp->fd, fp->buffer, fp->end);
        syncfs(fp->fd);
        fp->end = 0;
      }
      break;
    case 2:
      break;
    default:
      break;
  }
}

void _fflust(MYFILE *fp){
  assert(fp != NULL);
  if(fp->end > 0)
  {
    write(fp->fd, fp->buffer, fp->end);
    syncfs(fp->fd);
    fp->end = 0;
  }
}

void _fclose(MYFILE *fp){
  assert(fp != NULL);
  _fflust(fp);
  close(fp->fd);
  free(fp);
}


int main(){
  //close(1);
  MYFILE *fp = _fopen("./log.txt", "w");
  if(fp == NULL)
  {
    perror("_fopen");
    return 1;
  }

  //_fputs("hello one! ", fp);
  //_fputs("hello two! \n", fp);
  //_fputs("hello three! ", fp);
  //_fputs("hello four! \n", fp);
  
  _fputs("hello world!\n", fp);
  fork();

  _fclose(fp);
}
